
#ifndef _PROJECTZ_NCOMMAND_NWORLD_CS_CHAT_MESSAGE_H_
#define _PROJECTZ_NCOMMAND_NWORLD_CS_CHAT_MESSAGE_H_

#include "../../engine.h"

#include "../../User.h"
#include "../../Proxy.h"

#include "../../NLogic/Static.h"
#include "../../NLogic/Bag.h"
#include "../../NLogic/Item.h"
#include "../../NLogic/Score.h"
#include "../../NLogic/Function.h"
#include "../../NLogic/SocialInfo.h"
#include "../../NLogic/VirtualCurrency.h"
#include "../../NResource/Static.h"

#include "../../Config.h"

#include "../../../../protocol/iFriends.h"

namespace ProjectZ { namespace NCommand { namespace NWorld {

enum
{
	CHATTYPE_NOTICE = 0,
	CHATTYPE_ALL,
	CHATTYPE_PARTY,
	CHATTYPE_GUILD,
	CHATTYPE_WHISPER,
	CHATTYPE_FRIEND,
	CHATTYPE_MACRO,
	CHATTYPE_MARKET,
	CHATTYPE_CONNECT,
	CHATTYPE_BOAST,
	CHATTYPE_ALARM,
};

class CS_CHAT_MESSAGE
{
public:
	static void OnExecute(User * pUser, ::Network::Packet * pPacket)
	{
		PREPARE_PACKET;

		uint8_t type = 0;
		Toolkit::Str<1024> message;
		uint32_t sender_gid = 0;
		uint32_t receiver_gid = 0;

		*pPacket >> type >> message >> sender_gid >> receiver_gid;


		if (true == ::ProjectZ::Config::Instance().GetResourceDatabase()._isTest)
		{
			if( message.c_str()[0] == '+')
			{
				int exp = atoi(message.c_str()+1);
				FILELOG("EEEEEEEEEEEE================%d", exp);
				ProjectZ::NLogic::NFunction::IncreaseExp(pUser, exp);
			}

			// 아이템 복사
			if (message.c_str()[0] == '*')
			{
				int zen = atoi(message.c_str()+1);
				int nowZen = 0;
				pUser->GetVirtualCurrency()->AddZen(zen, nowZen);
			}

			// 전투펫 생성
			if (message.c_str()[0] == '@')
			{
				int score = atoi(message.c_str() + 1);
				pUser->GetUserInfo().wp_last_week = score;
				pUser->GetScore()->SetMemcache();
				pUser->FlushUserInfoCache();

//				int level = atoi(message.c_str() + 1);
//
//				// 1성
//				NResource::Static::InstancePtr()->GetBattlepetGachya()->BattlePetGachyaForTEST(pUser, level, 0);
//
//				// 6성
//				NResource::Static::InstancePtr()->GetBattlepetGachya()->BattlePetGachyaForTEST(pUser, level, 5);
			}

			// 페어리 생성
			if (message.c_str()[0] == '$')
			{
//				int level = atoi(message.c_str() + 1);
//				NResource::Static::InstancePtr()->GetFairyGachya()->FairyGachyaForTEST(pUser, level);

//				int score = atoi(message.c_str() + 1);
//				pUser->GetUserInfo().wp_cur_week = score;
//				pUser->GetUserInfo().wp_reg_date = time(NULL);
//				pUser->GetScore()->SetMemcache();
//				pUser->FlushUserInfoCache();

				int gold = atoi(message.c_str() + 1);
				pUser->GetCharacterInfo().gold += gold;
				pUser->FlushCharacterInfoCache();
			}

			// 페어리알, 전투펫알 메일로 발송
			if (message.c_str()[0] == '%')
			{
//				int gold = atoi(message.c_str() + 1);
//				pUser->GetCharacterInfo().gold += gold;
//				pUser->FlushCharacterInfoCache();

				int tid = atoi(message.c_str() + 1);

				NLogic::Item::Data clsData;
				clsData.tid = tid;
				clsData.sub_type = CLASS_ITEM_TABLE_CHARGE;
				clsData.quantity = 1;
				clsData.class_type = -1;
				NResource::Static::InstancePtr()->GetItemResource()->setItemEffect(clsData);
//				NResource::Static::InstancePtr()->GetItemResource()->SetItemDataFromResource(pUser, clsData);

				NLogic::MailBox::Mail::Data clsMailData;
				clsMailData.send_user_seq		= 0;
				clsMailData.send_user_nickname	= "GAMEVIL";
				clsMailData.recv_user_seq		= pUser->GetUserSeq();
				clsMailData.gift_status			= EM_GIFT_ITEM;
				clsMailData.item				= clsData;
				clsMailData.message				= "Oops! This is Cheat!!";

				NLogic::NFunction::SendMail(pUser, clsMailData);
			}

			// 우정 포인트 증가...
			if (message.c_str()[0] == '&')
			{
				//pUser->GetSocialInfo()->GetData()->_heart_count += 20;

				AddHeartCountSyn msg;
				msg.heart_count_max = 20;
				msg.get_heart_count = 20;

				::ProjectZ::NProxy::SendFriendsServer(pUser->GetUserSeq(), msg);

				DEBUGLOG("heart count cheat _heart_count : %d", pUser->GetSocialInfo()->GetData()->_heart_count);
			}
		}

		// 긴급 메시지
		if (strncmp(message.c_str(), "#!", 2) == 0)
		{
			if (strncmp(pUser->GetSocialID().c_str(), "00000000000000000", 17) == 0)
			{
				Toolkit::Str<1024> notice = "!cff0000";
				int msg_len = strlen(message.c_str()) - 2;

				if (msg_len <= 0)
					return;

				notice.Append(message.c_str() + 2, msg_len);

				DEBUGLOG("Oops!! EMERGENCY NOTICE=%s", notice.c_str());

				auto iter = NProxy::GetUserTree().begin();

				::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
				*pAck << notice.c_str();
				pAck->MakePacket(CMD_SC_EMERGENCY_NOTICE);

				for (; iter != NProxy::GetUserTree().end(); ++iter)
				{
					iter->second->SendOneshotEncrypt(pAck);
				}
				::Network::GETPACKETPOOL()->SEND_DEL(pAck);

				return;
			}
		}

		if (strncmp(message.c_str(), "##reload", 8) == 0)
		{
			if (strncmp(pUser->GetSocialID().c_str(), "00000000000000000", 17) == 0)
			{
				bool bLoad = NResource::Static::InstancePtr()->LoadResource(NResource::Static::E_TYPE::_ALL_);
				DEBUGLOG("RELOAD RESOURCE RESULT=%d", bLoad);

				bLoad = Config::Instance().LoadDatabase();
				DEBUGLOG("RELOAD CONFIG RESULT=%d", bLoad);
			}

			return;
		}

		if( type == CHATTYPE_PARTY || type == CHATTYPE_MACRO )
		{
			NLogic::Space * pSpace = pUser->GetSpace();
			if (NULL == pSpace)
				return;

			printf("type == CHATTYPE_PARTY || type == CHATTYPE_MACRO\n");
			const NLogic::Space::USERTREE & clsUserTree = pSpace->GetUserTree();
			std::for_each(clsUserTree.begin(), clsUserTree.end(), [&](const std::pair<const int, ProjectZ::User*>& pair) {

				::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
				* pNoti << static_cast<uint16_t>(ACK_OK) << type;

				if(1 == pUser->GetSocialInfo()->GetData()->_profile_opened)
					* pNoti	<< pUser->GetUserInfo().nickname.c_str();
				else
					* pNoti << static_cast<uint16_t>(0);

				* pNoti	<< pair.second->GetUserInfo().nickname.c_str()
						<< message.c_str() << sender_gid << receiver_gid;
				pNoti->MakePacket(CMD_SN_CHAT_MESSAGE);

				pair.second->Send(pNoti);
			} );
		}
		else if( type == CHATTYPE_WHISPER || type == CHATTYPE_MARKET || type == CHATTYPE_CONNECT )
		{
			printf("type == CHATTYPE_WHISPER || type == CHATTYPE_MARKET || type == CHATTYPE_CONNECT \n");
			User * receiver = NProxy::GetUser(receiver_gid);
			if(NULL != receiver)
			{
				DEBUGLOG("GuildChat> 10. receiver_gid: %u", receiver_gid);

				::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
				* pNoti << static_cast<uint16_t>(ACK_OK) << type;
				if(1 == pUser->GetSocialInfo()->GetData()->_profile_opened)
					* pNoti << pUser->GetUserInfo().nickname.c_str();
				else
					* pNoti << static_cast<uint16_t>(0);
				* pNoti << receiver->GetUserInfo().nickname.c_str() << message.c_str() << sender_gid << receiver_gid;
				pNoti->MakePacket(CMD_SN_CHAT_MESSAGE);

				receiver->Send(pNoti);
			}
			else
			{
				DEBUGLOG("GuildChat> 20. receiver_gid: %u", receiver_gid);

				::ProjectZ::NProxy::Chat(pUser, type, receiver_gid, message.c_str());
			}
		}
		else if( type == CHATTYPE_GUILD )
		{
			if ( 0 >= pUser->GetGuildSeq() )
			{
				//DEBUGLOG("%s> FAILED> guild chat> ACK_GUILD_NOT_SIGNED", __FUNCTION__ );

				std::string strTemp = "system";
				::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
				*pAck << static_cast<int16_t>(ACK_GUILD_NOT_SIGNED);
				*pAck << static_cast<uint8_t>(::ProjectZ::NCommand::NWorld::CHATTYPE_GUILD);
				*pAck << strTemp.c_str();
				*pAck << static_cast<uint16_t>(0); // 받는 유저명
				*pAck << message.c_str();
				*pAck << static_cast<uint32_t>(pUser->GetUserSeq());
				*pAck << static_cast<uint32_t>(0);
				pAck->MakePacket(CMD_SN_CHAT_MESSAGE);

				pUser->Send(pAck);
				return;
			}


			GuildChatSyn syn;
			syn.user_seq	= pUser->GetUserSeq();
			syn.guild_seq = pUser->GetGuildSeq();
			syn.chat = message.c_str();

			//DEBUGLOG("%s> guild chat> sender_seq: %d, guild_seq: %d, chat: %s", __FUNCTION__, syn.user_seq, syn.guild_seq, syn.chat.c_str() );


			if (false == NProxy::SendGuildServer(pUser, syn))
			{
				//DEBUGLOG("%s> FAILED> 39", __FUNCTION__ );

				::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
				*pAck << static_cast<int16_t>(ACK_UNKNOWN_ERROR);
				pAck->MakePacket(CMD_SN_CHAT_MESSAGE);
				pUser->Send(pAck);
				return;
			}
		}
		else		// CHATTYPE_NOTICE, CHATTYPE_ALL
		{
			printf("CHATTYPE_NOTICE, CHATTYPE_ALL\n");
			const std::map<int, User *>& s_user = ::ProjectZ::NProxy::GetUserTree();
			std::map<int, User *>::const_iterator iter = s_user.begin();
			for(;iter != s_user.end(); ++iter)
			{
				User *other = (*iter).second;
				::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
				* pNoti << static_cast<uint16_t>(ACK_OK) << type;
				if(1 == pUser->GetSocialInfo()->GetData()->_profile_opened)
					* pNoti << pUser->GetUserInfo().nickname.c_str();
				else
					* pNoti << static_cast<uint16_t>(0);
				* pNoti << other->GetUserInfo().nickname.c_str() << message.c_str() << sender_gid << receiver_gid;
				pNoti->MakePacket(CMD_SN_CHAT_MESSAGE);
				other->Send(pNoti);
			}
		}
	}
};

} /*NWorld*/ } /*NCommand*/ } /*ProjectZ*/


#endif /* _PROJECTZ_NCOMMAND_NWORLD_CS_CHAT_MESSAGE_H_ */
